home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 476-500 / disk_500 / wiconify / wiconify-source.lzh / Source / wGadget.c < prev    next >
C/C++ Source or Header  |  1991-04-19  |  12KB  |  375 lines

  1. /*
  2.  *  WICONIFY    A utility that allows you to iconify any Intuition window
  3.  *              on any screen, and to open WB windows on any screen.
  4.  *
  5.  *  wGadget.c   Handles the icon gadgets for the backdrop windows.
  6.  *
  7.  *  Copyright 1990 by Davide P. Cervone, all rights reserved.
  8.  *  You may use this code, provided this copyright notice is kept intact.
  9.  */
  10.  
  11. #define INTUITION_PREFERENCES_H             /* don't need 'em */
  12. #include <intuition/intuitionbase.h>
  13. #include "wHandler.h"
  14.  
  15. #define SELECTEDICON ((WICONREF *)(theIcon->Screen->Selected->Gadget.UserData))
  16. #define BOOLINFO     ((struct BoolInfo *)theGadget->SpecialInfo)
  17. #define GADGICON     ((WICONREF *)(theGadget->UserData))
  18.  
  19.  
  20. /*
  21.  *  SetupGadget()
  22.  *
  23.  *  If the icon is a screen icon use the screen defaults
  24.  *  Otherwise use the window icon defaults
  25.  *  Get the icon's image
  26.  *  Set the gadget variables appropriately (UserData points to the icon)
  27.  *  Set the render and select imagery
  28.  *  Set the gadget's text (use the window title for the name if none supplied)
  29.  *  Set the gadget's mask
  30.  *  Initialize the gadget's position on the screen
  31.  */
  32.  
  33. void SetupGadget(theIcon)
  34. WICONREF *theIcon;
  35. {
  36.    struct Image *DefImage,*DefSelect,*DefMask;
  37.    struct Image *theImage;
  38.    struct Gadget *theGadget = &(theIcon->Gadget->Gadget);
  39.    struct IntuiText *theText = &(theIcon->Gadget->IText);
  40.    struct BoolInfo *theInfo = &(theIcon->Gadget->Mask);
  41.  
  42.    if (theIcon->Icon.Flags & WI_SCREENICON)
  43.    {
  44.       DefImage  = DefaultScreenImage;
  45.       DefSelect = DefaultScreenSelect;
  46.       DefMask   = DefaultScreenMask;
  47.    } else {
  48.       DefImage  = DefaultImage;
  49.       DefSelect = DefaultSelect;
  50.       DefMask   = DefaultMask;
  51.    }
  52.    theImage = (theIcon->Icon.Image)? theIcon->Icon.Image: DefImage;
  53.  
  54.    theGadget->UserData = (APTR) theIcon;
  55.    theGadget->LeftEdge = theIcon->Icon.x;
  56.    theGadget->TopEdge  = theIcon->Icon.y;
  57.    theGadget->NextGadget = NULL;
  58.    theGadget->Width  = theImage->Width;
  59.    theGadget->Height = theImage->Height;
  60.    theGadget->Activation = GADGIMMEDIATE;
  61.    theGadget->GadgetType = BOOLGADGET;
  62.    theGadget->MutualExclude = 0L;
  63.  
  64.    theGadget->Flags = GADGIMAGE | GADGHNONE;
  65.    theGadget->GadgetRender = (APTR) theImage;
  66.    if (theIcon->Icon.Select)
  67.       theGadget->SelectRender = (APTR)theIcon->Icon.Select;
  68.    else if (theImage == DefImage && DefSelect)
  69.       theGadget->SelectRender = (APTR)DefSelect;
  70.  
  71.    theGadget->GadgetText = theText;
  72.       theText->FrontPen  = TEXTPEN;
  73.       theText->BackPen   = BACKGROUND;
  74.       theText->DrawMode  = JAM2;
  75.       theText->TopEdge   = (theImage->Height + 2);
  76.       theText->ITextFont = theIcon->Screen->Screen->Font;
  77.       theText->NextText  = NULL;
  78.       if (theIcon->Icon.Name)     theText->IText = theIcon->Icon.Name;
  79.       else if (theIcon->Window)   theText->IText = theIcon->Window->Title;
  80.       if (theText->IText == NULL) theText->IText = "[No Title]";
  81.       theText->LeftEdge  = (theImage->Width - IntuiTextLength(theText)) / 2;
  82.  
  83.    theInfo->Flags = BOOLMASK;
  84.    if (theIcon->Icon.Mask) theInfo->Mask = (UWORD *)theIcon->Icon.Mask;
  85.    else if (theImage == DefImage && theImage != NULL && DefMask)
  86.       theInfo->Mask = DefMask->ImageData;
  87.    if (theGadget->SelectRender == NULL && theInfo->Mask)
  88.       theGadget->Activation |= BOOLEXTEND;
  89.    theGadget->SpecialInfo = (APTR) theInfo;
  90.  
  91.    InitPosition(theGadget);
  92. }
  93.  
  94.  
  95. /*
  96.  *  UnLinkGadget()
  97.  *
  98.  *  If the gadget is selected unlink it from the selection list
  99.  */
  100.  
  101. void UnLinkGadget(theGadget)
  102. struct wGadget *theGadget;
  103. {
  104.    Forbid();
  105.    if (GADGETICON->Icon.Flags & WI_SELECTED)
  106.    {
  107.       if (theGadget->NextSelect)
  108.          theGadget->NextSelect->PrevSelect = theGadget->PrevSelect;
  109.       if (theGadget->PrevSelect)
  110.          theGadget->PrevSelect->NextSelect = theGadget->NextSelect;
  111.       else GADGETICON->Screen->Selected = theGadget->NextSelect;
  112.    }
  113.    Permit();
  114. }
  115.  
  116.  
  117. /*
  118.  *  MakeSelected()
  119.  *
  120.  *  Clear the highlight flags
  121.  *  If the gadget has a select image
  122.  *    If it has a mask, mark the gadget as having one
  123.  *    Mark the gadget as having an image
  124.  *  Otherwise
  125.  *    Mark it as a complementing gadget
  126.  */
  127.  
  128. void MakeSelected(theGadget)
  129. struct Gadget *theGadget;
  130. {
  131.    theGadget->Flags &= ~GADGHIGHBITS;
  132.    if (theGadget->SelectRender)
  133.    {
  134.       if (BOOLINFO->Mask) theGadget->Activation |= BOOLEXTEND;
  135.       theGadget->Flags |= SELECTED | GADGHIMAGE;
  136.    } else {
  137.       theGadget->Flags |= SELECTED | GADGHCOMP;
  138.    }
  139. }
  140.  
  141.  
  142. /*
  143.  *  MakeUnSelected()
  144.  *
  145.  *  Clear the selection and highlight flags
  146.  *  Set the highlighting to none
  147.  *  Remove the bool mask, if any
  148.  */
  149.  
  150. static void MakeUnSelected(theGadget)
  151. struct Gadget *theGadget;
  152. {
  153.    theGadget->Flags &= ~(SELECTED | GADGHIGHBITS);
  154.    theGadget->Flags |=  GADGHNONE;
  155.    if (theGadget->SelectRender && BOOLINFO->Mask)
  156.       theGadget->Activation &= ~BOOLEXTEND;
  157. }
  158.  
  159.  
  160. /*
  161.  *  DeselectIcon()
  162.  *
  163.  *  If dragging is currently in progress, cancel it
  164.  *  If the icon is selected
  165.  *    If the icon has a gadget and the screen had a wIconify window
  166.  *      Unlink the gadget from the selection list
  167.  *      Remove it from the screen
  168.  *      Mark it as unselected
  169.  *      Put it back on the screen
  170.  *      Mark the icon as unselected
  171.  *      Refresh the icons on the given screen
  172.  *      Report the unselect event, if necessary
  173.  *    If no more icons are selected, update the menus (turn off OpenAll, etc)
  174.  */
  175.  
  176. void DeselectIcon(theIcon)
  177. WICONREF *theIcon;
  178. {
  179.    LONG GadgetPos;
  180.    struct Gadget *theGadget = &theIcon->Gadget->Gadget;
  181.  
  182.    if (theIcon->Screen->Flags & (WI_DRAGGING| WI_STARTDRAG))
  183.        CancelDragging(theIcon->Screen);
  184.    if (theIcon->Icon.Flags & WI_SELECTED)
  185.    {
  186.       if (theGadget && theIcon->Screen->BackDrop)
  187.       {
  188.          Forbid();
  189.          UnLinkGadget(theGadget);
  190.          GadgetPos = RemoveGadget(theIcon->Screen->BackDrop,theGadget);
  191.          MakeUnSelected(theGadget);
  192.          AddGadget(theIcon->Screen->BackDrop,theGadget,GadgetPos);
  193.          theIcon->Icon.Flags &= ~WI_SELECTED;
  194.          Permit();
  195.          RefreshIcons(theIcon->Screen,FALSE);
  196.          if (theIcon->Icon.Report & WI_REPORTUNSELECT)
  197.             ReportEvent(WI_REPORTUNSELECT,theIcon);
  198.       }
  199.       if (theIcon->Screen->Selected == NULL) UpdateActiveMenu();
  200.    }
  201. }
  202.  
  203.  
  204. /*
  205.  *  DeselectAll()
  206.  *
  207.  *  If the screen has a wIconify window
  208.  *    If icons are being dragged, cancel the dragging
  209.  *    While there are more selected icons
  210.  *      Remove the selected gadget from the screen
  211.  *      Mark it as unselected
  212.  *      Put it back on screen
  213.  *      Clear its links to other selected gadgets and mark it as unselected
  214.  *      Report the unselect event, if necessary
  215.  *    Refresh the screen's icons
  216.  *    Update the menus (turn off OpenAll, etc)
  217.  */
  218.  
  219. void DeselectAll(theScreen)
  220. WSCREEN *theScreen;
  221. {
  222.    LONG GadgetPos;
  223.    struct wGadget *theGadget;
  224.  
  225.    if (theScreen && theScreen->BackDrop)
  226.    {
  227.       Forbid();
  228.       if (theScreen->Flags & (WI_DRAGGING| WI_STARTDRAG))
  229.           CancelDragging(theScreen);
  230.       while ((theGadget = theScreen->Selected) != NULL)
  231.       {
  232.          GadgetPos = RemoveGadget(theScreen->BackDrop,theGadget);
  233.          MakeUnSelected(&theGadget->Gadget);
  234.          AddGadget(theScreen->BackDrop,theGadget,GadgetPos);
  235.          theScreen->Selected = theGadget->NextSelect;
  236.          theGadget->NextSelect = NULL;
  237.          theGadget->PrevSelect = NULL;
  238.          GADGETICON->Icon.Flags &= ~WI_SELECTED;
  239.          if (GADGETICON->Icon.Report & WI_REPORTUNSELECT)
  240.             ReportEvent(WI_REPORTUNSELECT,GADGETICON);
  241.       }
  242.       Permit();
  243.       RefreshIcons(theScreen,FALSE);
  244.       UpdateActiveMenu();
  245.    }
  246. }
  247.  
  248.  
  249. /*
  250.  *  SelectIcon()
  251.  *
  252.  *  If an icon was given
  253.  *    Get its screen
  254.  *    If no icons are being dragged on the screen
  255.  *      Get the icons gadget
  256.  *      If the SHIFT key was pressed
  257.  *        If the icon is already selected
  258.  *          Deselect it and clear the gadget
  259.  *        Otherwise if there were any select icons
  260.  *          If this icon or the selected one does not allow multiple selection
  261.  *            Clear the gadget
  262.  *      Otherwise (SHIFT not pressed)
  263.  *        If the icon is already selected, unlink it (we'll relink it later)
  264.  *        Otherwise deselect all selected icons
  265.  *      If we still have a gadget and a window to work with,
  266.  *        Remove the gadget from the screen
  267.  *        Mark it as selected and replace it on the screen
  268.  *        Mark the icon as selected
  269.  *        Link the gadget into the selected-gadget list
  270.  *        Refresh the screen's icons
  271.  *        Update the menus (activate OpenAll, etc)
  272.  *        Report the selection event, if necessary
  273.  */
  274.  
  275. void SelectIcon(theIcon,Shifted)
  276. WICONREF *theIcon;
  277. int Shifted;
  278. {
  279.    WSCREEN *theScreen;
  280.    struct wGadget *theGadget;
  281.    int AlreadySelected = FALSE;
  282.  
  283.    if (theIcon)
  284.    {
  285.       Forbid();
  286.       theScreen = theIcon->Screen;
  287.       if ((theScreen->Flags & WI_DRAGGING) == 0)
  288.       {
  289.          theGadget = theIcon->Gadget;
  290.          if (Shifted)
  291.          {
  292.             if (theIcon->Icon.Flags & WI_SELECTED)
  293.             {
  294.                DeselectIcon(theIcon);
  295.                theGadget = NULL;
  296.             } else if (theIcon->Screen->Selected) {
  297.                if ((theIcon->Icon.Flags & WI_NOMULTISELECT) ||
  298.                    (SELECTEDICON->Icon.Flags & WI_NOMULTISELECT))
  299.                       theGadget = NULL;
  300.             }
  301.          } else {
  302.             AlreadySelected = (theIcon->Icon.Flags & WI_SELECTED);
  303.             if (AlreadySelected)
  304.                UnLinkGadget(theGadget); else DeselectAll(theScreen);
  305.          }
  306.          if (theGadget && theScreen->BackDrop)
  307.          {
  308.             RemoveGadget(theScreen->BackDrop,theGadget);
  309.             MakeSelected(&theGadget->Gadget);
  310.             AddGadget(theScreen->BackDrop,theGadget,0);
  311.             GADGETICON->Icon.Flags |= WI_SELECTED;
  312.  
  313.             theGadget->PrevSelect = NULL;
  314.             theGadget->NextSelect = theScreen->Selected;
  315.             if (theScreen->Selected)
  316.                 theScreen->Selected->PrevSelect = theGadget;
  317.             theScreen->Selected = theGadget;
  318.             RefreshIcons(theIcon->Screen,FALSE);
  319.             UpdateActiveMenu();
  320.             if ((GADGETICON->Icon.Report & WI_REPORTSELECT) &&
  321.                  AlreadySelected == FALSE)
  322.                     ReportEvent(WI_REPORTSELECT,GADGETICON);
  323.          }
  324.       }
  325.       Permit();
  326.    }
  327. }
  328.  
  329.  
  330. /*
  331.  *  MoveGadget()
  332.  *
  333.  *  If we have a gadget and a window to work with
  334.  *    Check that the position is within the window bounds
  335.  *    If the gadget has moved,
  336.  *       Remove the gadget from the screen
  337.  *       Set the new position
  338.  *       Put the icon back on the screen
  339.  *       Refresh the screen's icons
  340.  *       Report the move event, if necessary
  341.  */
  342.  
  343. void MoveGadget(theGadget,dx,dy,theScreen)
  344. struct Gadget *theGadget;
  345. WORD dx,dy;
  346. WSCREEN *theScreen;
  347. {
  348.    LONG GadgetPos;
  349.    WORD NewX = theGadget->LeftEdge + dx;
  350.    WORD NewY = theGadget->TopEdge  + dy;
  351.  
  352.    if (theGadget && theScreen->BackDrop)
  353.    {
  354.       if (NewX < 0) NewX = 0;
  355.       if (NewX > theScreen->BackDrop->Width - theGadget->Width)
  356.          NewX = theScreen->BackDrop->Width - theGadget->Width;
  357.       if (NewY < 0) NewY = 0;
  358.       if (NewY > theScreen->BackDrop->Height - theGadget->Height - 10)
  359.          NewY = theScreen->BackDrop->Height - theGadget->Height - 10;
  360.  
  361.       if (theGadget->LeftEdge != NewX || theGadget->TopEdge != NewY)
  362.       {
  363.          Forbid();
  364.          GadgetPos = RemoveGadget(theScreen->BackDrop,theGadget);
  365.          theGadget->LeftEdge = NewX; GADGICON->Icon.x = NewX;
  366.          theGadget->TopEdge  = NewY; GADGICON->Icon.y = NewY;
  367.          AddGadget(theScreen->BackDrop,theGadget,GadgetPos);
  368.          Permit();
  369.          RefreshIcons(theScreen,TRUE);
  370.          if (GADGICON->Icon.Report & WI_REPORTMOVED)
  371.             ReportEvent(WI_REPORTMOVED,theGadget->UserData);
  372.       }
  373.    }
  374. }
  375.